import { defineStore } from 'pinia'
import { childRouter } from '@/router'
import router from '@/router'
import useLoginStore from '@/stores/login-store'
import { startCase } from 'lodash-es'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getUserMenuTreeMockApi } from '@/api/mock-js/system/menu-permit-api'

const useMenuStore = defineStore('menuStore', {
    state: () => ({
        // isCloseLeftMenu: false, // 隐藏左侧菜单,
        activeMenu: {}, // 当前路由,包括children
        activePath: '', // 当前路由 router.currentRoute.value.fullPath
        layoutMenuTree: [], // 后台的菜单树
        layoutFormList: [], // 用户的表单list,用于表单跳转，不显示在layoutMenuTree的模块都存在这里
        layoutTabList: [], // 后台的多页签List
        keepAliveList: [], // 需要缓存的后台路由
    }),
    getters: {},
    actions: {
        /*点击左侧菜单跳转
        * @params {string} parentPath 父级路由
        * @params {string} path 子级路由
        * @params {string} pathName 子级路由名称
        * @params {string} type 跳转的页面类型 ‘form’-表单
        * @params {Object} params 跳转form携带的路由参数
         */
        handleActivePath(menuItem, type, params = {}) {
            const _tabPane = {
                permissionTopPath: menuItem.permissionTopPath,
                permissionPath: menuItem.permissionPath,
                permissionName: menuItem.permissionName
            }
            const _result = this.layoutTabList.filter(item => JSON.stringify(item) === JSON.stringify(_tabPane))
            // 获取permissionPath最后一个page,改为大驼峰式，缓存到 keep-alive内
            const _routeName = startCase(menuItem.permissionPath.split('/').slice(-1)[0]).replace(/\s+/g, '')
            if ( !_result.length) {
                if (this.layoutTabList.length > 20) {
                    ElMessage.warning('打开的模块太多，请先关闭一些页面！')
                    // el-menu无法打断跳转，因此需要在这里设置跳回原来的页面
                    router.push({path: this.activePath}).then()
                    return
                }
                if (type === 'form') {
                    const _formIndex = this.layoutTabList.findIndex(({permissionTopPath, permissionPath}) => {
                        return menuItem.permissionTopPath===permissionTopPath && ('/'+menuItem.permissionPath.split('/')[1]===permissionPath)
                    })
                    this.layoutTabList.splice(_formIndex+1,0,_tabPane)
                } else {
                    this.layoutTabList.push(_tabPane)
                }
                window.sessionStorage.setItem('layoutTabList', JSON.stringify(this.layoutTabList))
                this.keepAliveList.push(_routeName)
                window.sessionStorage.setItem('keepAliveList', JSON.stringify(this.keepAliveList))
            }
            this.activePath = `${menuItem.permissionTopPath}${menuItem.permissionPath}`
            window.sessionStorage.setItem('activePath', this.activePath)
            // 清空旧缓存
            window.sessionStorage.setItem(_routeName + 'Params', null)
            if ( !!params && params !== {}) {
                // 保存参数
                window.sessionStorage.setItem(_routeName + 'Params', JSON.stringify(params))
            }
            router.push({path: this.activePath}).then()
        },
        /* 点击导航栏跳转：保存选中的顶部导航栏，children用于左侧菜单栏
        *  @params {string} routerPath 顶部导航栏的路由
        * */
        handleActiveMenu(navItem) {
            const parentPath = navItem.permissionTopPath ?? navItem.permissionPath
            this.activeMenu = this.layoutMenuTree.filter(({permissionPath}) => permissionPath === parentPath)?.[0]
            window.sessionStorage.setItem('activeMenu', JSON.stringify(this.activeMenu))
            if (this.activeMenu?.children?.length) {
                // 存在 permissionTopPath时，为点击多页签跳转
                if (navItem.permissionTopPath) {
                    this.handleActivePath(navItem)
                } else {
                    // 左侧菜单栏或者头部导航栏跳转时
                    this.handleActivePath(this.activeMenu.children[0])
                }
            }
        },
        /* 点击多页签跳转
        *  @params {string} label 为方便传输，已经把 该页签的所有数据转为字符串存在label内
         */
        handleActiveTab(label) {
            let _label = label
            if (typeof label === 'string') {
                _label = JSON.parse(label)
            }
            this.handleActiveMenu(_label)
        },
        /* 表单的路由跳转 请注意大小写！
        *  @params {string} path 跳转的permissionPath，一般为 ’/父级/子级‘ 两层
        *  @params {string} topPath 顶级路由，来自 ‘系统管理-菜单与权限’中填入的‘父级路由’ 字段
        *  @params {object} params 路由参数，编辑表单时需要
        *  @params {number} editFlag 编辑状态 0:新增 1:编辑 2:只读（默认只读 防止初加载时出现 编辑按钮） 3.审批（预留字段）
        * */
        handleFormRouter(path, topPath, params = {}, editFlag = 2) {
            // 获取form的路由信息
            const target = this.layoutFormList.filter(item => item.permissionPath === path && item.permissionTopPath === topPath)?.[0]
            // 判断该form是否存在多页签
            const hasOpenTab = this.layoutTabList.filter(item => item.permissionPath === path && item.permissionTopPath === topPath)?.[0]
            if (hasOpenTab) {
                // 存在多页签时，提示已打开，和确认是否跳转
                ElMessageBox.confirm(`模块-${hasOpenTab.permissionName}存在编辑中的表单，是否跳转继续修改？`, '提示', {}).then(() => {
                    this.handleActiveTab(hasOpenTab)
                })
            } else {
                // 如果不存在的form页签，则新增多页签+跳转
                if (editFlag) params.editFlag = editFlag
                this.handleActivePath(target, 'form', params)
            }
        },
        /* 关闭多页签
         * @params {string} panePath 当前页签的permissionPath
         */
        handleRemoveTab(panePath) {
            if (this.layoutTabList.length === 1) {
                ElMessage.warning('请保证至少打开一个模块！')
                return
            }
            // 删除params缓存
            if (window.sessionStorage.getItem(router.currentRoute.value.name + 'Params')) {
                window.sessionStorage.setItem(router.currentRoute.value.name + 'Params', null)
            }
            // 删除缓存 keep-alive start
            const _routeName = startCase(panePath.split('/').slice(-1)[0]).replaceAll(' ', '')
            this.keepAliveList = this.keepAliveList.filter(item => item !== _routeName)
            // 删除缓存 keep-alive end
            let _index = this.layoutTabList.length
            for (let i = 0; i < this.layoutTabList.length; i++) {
                if ((this.layoutTabList[i].permissionTopPath + this.layoutTabList[i].permissionPath) === panePath) {
                    // 如果关闭的是当前页签,需要设置当前页签为前一个或者后一个
                    if (this.activePath === panePath) {
                        switch (i) {
                            case 0:
                                _index = 1
                                break
                            case this.layoutTabList.length:
                                _index = i - 1
                                break
                            default:
                                _index = i - 1
                                break
                        }
                        // 需要重新设置一下选中页签，其他情况不需要
                        this.handleActiveTab(this.layoutTabList[_index])
                    }
                    break
                }
            }
            this.layoutTabList = this.layoutTabList.filter(({
                                                                      permissionTopPath,
                                                                      permissionPath
                                                                  }) => (permissionTopPath + permissionPath) !== panePath)
            window.sessionStorage.setItem('layoutTabList', JSON.stringify(this.layoutTabList))
        },
        /* 批量关闭多页签
        *  @params {string} type 批量关闭类型 left:关闭左侧 right:关闭右侧 others:关闭其他
        * @params {string} path 当前页签的permissionPath
         */
        BatchRemoveTab(type, path) {
            if (type === 'others') {
                this.layoutTabList = this.layoutTabList.filter(({
                                                                          permissionTopPath,
                                                                          permissionPath
                                                                      }) => (permissionTopPath + permissionPath) === path)
                window.sessionStorage.setItem('keepAliveList', JSON.stringify(this.keepAliveList))
                if (path !== this.activePath) {
                    this.handleActiveTab(this.layoutTabList[0])
                }
            } else if (type === 'left' || type === 'right') {
                const index = this.layoutTabList.findIndex(({
                                                                   permissionTopPath,
                                                                   permissionPath
                                                               }) => (permissionTopPath + permissionPath) === path)
                // 获取删除的页签区间
                const range = type === 'left' ? [0, index] : [index + 1, this.layoutTabList.length]
                const delList = this.layoutTabList.slice(range[0], range[1])
                // 如果当前页签在两侧,不用执行批量关闭操作
                if ( !delList.length) {
                    ElMessage.info('没有可关闭的页签！')
                    return
                }
                // hasActTab=true时,代表 删除的页签里是否包括当前打开的模块
                const hasActTab = delList.filter(({
                                                      permissionTopPath,
                                                      permissionPath
                                                  }) => (permissionTopPath + permissionPath) === this.activePath)?.[0]
                // 设置当前页签为打开的模块
                if (hasActTab) {
                    this.handleActiveTab(this.layoutTabList[index])
                }
                // 开始批量删除操作
                const delRange = [range[0], range[1] - range[0]]
                // 删除对应的缓存  拼接组件名字,startCase:首字母大写;replaceAll():去掉startCase()方法生成的所有空格
                const delKeepAlives = delList.map(({permissionPath}) => startCase(permissionPath.split('/').slice(-1)[0]).replaceAll(' ', ''))
                this.keepAliveList = this.keepAliveList.filter(item => !delKeepAlives.includes(item))
                window.sessionStorage.setItem('keepAliveList', JSON.stringify(this.keepAliveList))
                this.layoutTabList.splice(delRange[0], delRange[1])
                window.sessionStorage.setItem('layoutTabList', JSON.stringify(this.layoutTabList))
            }
        },
        /* 根据userInfo获取的权限过滤路由,插入到后台（backstage）的children内，404页面放children里可以显示导航栏*/
        filterRoleRouter() {
            const filterRoute = childRouter.filter(item => useLoginStore().userInfo?.roleAndPermissions?.includes('/' + item.path.split('/').splice(2).join('/')))
            // 页面布局路由重定向到首页子路由
            router.addRoute({
                path: '/',
                name: 'Layout',
                component: () => import('@/layout/Layout.vue'),
                meta: {
                    title: '首页'
                },
                children: [
                    {
                        path: '/:catchAll(.*)',
                        hidden: true,
                        component: () => import('@/components/404NotFound.vue')
                    },
                    ...filterRoute]
            })
        },
        /* 递归删除菜单里的表单路由（icon=isForm,），不在左侧显示
        * @params {array} target 用户的菜单树数组
        *  */
        recursiveRemoveFormMenu(target) {
            return target.reduce((prev, menu, index) => {
                if (menu.icon === 'isForm') {
                    // 把form模块存在 layoutFormList，然后从菜单列表中清除
                    this.layoutFormList.push(menu)
                    return prev
                }
                prev[index] = menu
                if (menu?.children?.length) {
                    prev[index].children = this.recursiveRemoveFormMenu(menu.children)
                }
                return prev
            }, [])
        },
        // 获取用户菜单树
        async getUserMenuTree() {
            try {
                const res = await getUserMenuTreeMockApi()
                let formList = res.data
                this.layoutFormList = []
                // 过滤表单数据(icon=isForm)，不显示在左侧菜单，存在layoutFormList内
                this.recursiveRemoveFormMenu(formList)
                this.layoutMenuTree = formList
                // 根据权限list过滤用户可见路由
                this.filterRoleRouter()
                const _tabList = JSON.parse(sessionStorage.getItem('layoutTabList'))
                const _activePath = sessionStorage.getItem('activePath')
                const _keepAlives = JSON.parse(sessionStorage.getItem('keepAliveList'))
                const _activeMenu = JSON.parse(sessionStorage.getItem('activeMenu'))
                if (_tabList?.length && !!_activePath && _keepAlives?.length && !!_activeMenu.permissionPath) {
                    this.layoutTabList = _tabList
                    this.activePath = _activePath
                    this.keepAliveList = _keepAlives
                    this.activeMenu = _activeMenu
                    router.push(_activePath).then()
                } else {
                    // 设置默认进入第一个模块的第一个子菜单
                    this.handleActiveMenu(this.layoutMenuTree[0])
                }
            } catch (e) {
            }
        }
    }
})
export default useMenuStore
